package org.fuys.coder.infrastructure.repository;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.fuys.coder.common.constants.RedisConstants;
import org.fuys.coder.infrastructure.model.dto.UserPermissionDTO;
import org.fuys.coder.common.exception.BaseException;
import org.fuys.coder.domain.auth.repository.IPermissionRepository;
import org.fuys.coder.infrastructure.dao.PermissionMapper;
import org.fuys.coder.infrastructure.dao.RolePermissionMapper;
import org.fuys.coder.infrastructure.dao.RoleUserMapper;
import org.fuys.coder.infrastructure.model.po.Permissions;
import org.fuys.coder.infrastructure.model.po.RolePermissions;
import org.fuys.coder.infrastructure.model.po.RolesUser;
import org.fuys.coder.infrastructure.util.RedisUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * @projectName: fuys-low-coder
 * @package: org.fuys.coder.infrastructure.repository
 * @className: PermissionRepositoryImpl
 * @author: WangJing
 * @description: 仓储实现类
 * @date: 2024/7/11 10:56
 * @version: 1.0
 */
@Service
public class PermissionRepositoryImpl extends ServiceImpl<PermissionMapper, Permissions>
        implements IPermissionRepository {

    @Resource
    private RedisUtil redisUtil;

    @Resource
    private RolePermissionMapper rolePermissionMapper;

    @Resource
    private RoleUserMapper roleUserMapper;


    @Override
    public List<UserPermissionDTO> getAllRoleDetail() {
        //这里没有使用JOIN查询 原因是如果join联查 连接的表有些根本不需要 内存方面为了防止启动时过大 因此选择时间换空间 反正启动嘛 无所谓
        //获取除开常驻和超级管理员的用户对应的角色信息 （角色ID和用户ID）
        Map<Integer,UserPermissionDTO> permissionDTOMap=new ConcurrentHashMap<>();
        Map<Integer,List<Integer>> rolePermissionMap=new ConcurrentHashMap<>();
        final List<RolesUser> rolesUsers = roleUserMapper.selectList(new LambdaQueryWrapper<RolesUser>()
                .select(RolesUser::getUserId, RolesUser::getRoleId));
        final Set<Integer> roleIds = rolesUsers.stream().map(RolesUser::getRoleId).collect(Collectors.toSet());
        //获取角色对应的权限信息 （角色ID来获取权限ID）
        final List<RolePermissions> rolePermissions = rolePermissionMapper.selectList(new LambdaQueryWrapper<RolePermissions>()
                .select(RolePermissions::getRoleId,RolePermissions::getPermissionId).in(RolePermissions::getRoleId, roleIds));
        //汇总
        rolePermissions.forEach((rolePermission)->{
            final Integer roleId = rolePermission.getRoleId();
            if(rolePermissionMap.containsKey(roleId)) {
                rolePermissionMap.get(roleId).add(rolePermission.getPermissionId());
            }else{
                List<Integer> roleToPermission=new ArrayList<>();
                roleToPermission.add(rolePermission.getPermissionId());
                rolePermissionMap.put(roleId,roleToPermission);
            }
        });
        rolesUsers.forEach((rolesUser)->{
            final Integer userId = rolesUser.getUserId();
            if(permissionDTOMap.containsKey(userId)) {
                throw new BaseException("一个用户只能担任一个角色!");
            }else{
                final UserPermissionDTO value = new UserPermissionDTO();
                final Integer roleId = rolesUser.getRoleId();
                value.setRoleId(roleId);
                value.setPermissions(rolePermissionMap.get(roleId));
                value.setUserId(userId);
                permissionDTOMap.put(userId, value);
            }
        });
        return new ArrayList<>(permissionDTOMap.values());
    }

    @Override
    public Object getUserPermission(Integer userId) {
        return redisUtil.commonGet(RedisConstants.REDIS_FIELD_USER + userId + RedisConstants.REDIS_SPLIT
                + RedisConstants.REDIS_USE_PERMISSION);
    }


}
